import datetime
import uuid
import random
import math
from flask import request, jsonify, current_app
from flask_jwt_extended import jwt_required, get_jwt
from sqlalchemy import desc
from app.core.extensions import db
from app.models import AdminLog
from app.models.agents import ActivationCode, ActivationCodeBatch, Agent
from . import admin_blueprint
from app.services.decorators import admin_required
from .utils import get_admin_id


# 添加生成唯一激活码的函数
def generate_unique_code(prefix='045', length=8):
    """
    生成唯一的激活码
    
    参数:
    - prefix: 激活码前缀，默认"045"
    - length: 除前缀外的数字长度，默认8位
    
    返回:
    - 唯一的激活码字符串
    """
    # 获取所有存在的激活码
    existing_codes = set([code.code for code in ActivationCode.query.all()])

    # 生成不重复的激活码
    while True:
        # 生成指定长度的随机数字
        min_val = 10 ** (length - 1)
        max_val = (10 ** length) - 1
        random_number = random.randint(min_val, max_val)

        # 组合成完整激活码
        code_str = f"{prefix}{random_number}"

        # 确保不重复
        if code_str not in existing_codes:
            return code_str


# 导入安全分页方法
try:
    from app.utils.pagination import safe_paginate
except ImportError:
    # 如果找不到自定义分页模块，使用手动分页实现
    def safe_paginate(query, page, per_page, error_out=False):
        """
        安全的分页方法，兼容不同版本的SQLAlchemy
        """
        # 计算总记录数
        total = query.count()

        # 计算总页数
        pages = math.ceil(total / per_page) if total > 0 else 1

        # 验证页码有效性
        if page < 1:
            page = 1
        elif page > pages and total > 0:
            page = pages

        # 计算偏移量
        offset = (page - 1) * per_page

        # 获取当前页的记录
        items = query.offset(offset).limit(per_page).all()

        # 创建类似pagination对象的结构
        class PaginationResult:
            def __init__(self, items, page, per_page, total, pages):
                self.items = items
                self.page = page
                self.per_page = per_page
                self.total = total
                self.pages = pages

        return PaginationResult(items, page, per_page, total, pages)


@admin_blueprint.route('/activation_codes', methods=['GET'])
@jwt_required()
def get_activation_codes_underscore():
    """获取激活码列表（带下划线的路由）"""
    return get_activation_codes()


@admin_blueprint.route('/activation-codes', methods=['GET', 'OPTIONS'])
@jwt_required(optional=True)
def get_activation_codes():
    """获取激活码列表
    
    查询参数:
    - page: 页码，默认1
    - per_page: 每页数量，默认20
    - search: 搜索关键词（激活码）
    - status: 状态筛选（0-未使用，1-已使用）
    - agent_id: 按代理ID筛选
    - batch_id: 按批次ID筛选
    - usage_count: 按使用次数筛选
    - is_copied: 是否已复制（1-已复制）
    - is_exported: 是否已导出（1-已导出）
    - expire_days: 按有效期天数筛选
    """
    # 获取分页参数
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 20, type=int)
    search = request.args.get('search', '')
    status = request.args.get('status', None, type=int)
    agent_id = request.args.get('agent_id', None, type=int)
    batch_id = request.args.get('batch_id', None)
    usage_count = request.args.get('usage_count', None, type=int)
    is_copied = request.args.get('is_copied', None, type=int)
    is_exported = request.args.get('is_exported', None, type=int)
    expire_days = request.args.get('expire_days', None, type=int)
    code = request.args.get('code', None, type=str)
    # 构建查询
    query = ActivationCode.query

    if code:
        query = query.filter(ActivationCode.code == code)
    # 根据状态筛选
    if status is not None:
        query = query.filter(ActivationCode.status == status)

    # 根据代理筛选
    if agent_id:
        query = query.filter(ActivationCode.created_by == agent_id)

    # 根据批次筛选
    if batch_id:
        query = query.filter(ActivationCode.batch_id == batch_id)

    # 关键词搜索
    if search:
        query = query.filter(ActivationCode.code.like(f'%{search}%'))

    # 根据使用次数筛选
    if usage_count is not None:
        query = query.filter(ActivationCode.usage_count == usage_count)

    # 根据是否已复制筛选
    if is_copied is not None:
        query = query.filter(ActivationCode.is_copied == bool(is_copied))

    # 根据是否已导出筛选
    if is_exported is not None:
        query = query.filter(ActivationCode.is_exported == bool(is_exported))

    # 根据有效期天数筛选
    if expire_days is not None:
        # 找出批次表中expire_days等于指定天数的批次
        batches = ActivationCodeBatch.query.filter_by(expire_days=expire_days).all()
        batch_ids = [batch.id for batch in batches]
        if batch_ids:
            query = query.filter(ActivationCode.batch_id.in_(batch_ids))
        else:
            # 如果没有找到匹配的批次，返回空结果
            return jsonify({
                'code': 0,
                'message': '获取成功',
                'data': {
                    'total': 0,
                    'pages': 0,
                    'page': page,
                    'per_page': per_page,
                    'items': []
                }
            })

    # 执行分页查询
    # 使用limit和offset代替paginate
    offset = (page - 1) * per_page
    total = query.count()
    codes = query.order_by(desc(ActivationCode.create_time)).offset(offset).limit(per_page).all()

    # 计算总页数
    pages = (total + per_page - 1) // per_page if total > 0 else 1

    # 构建响应数据
    result = {
        'code': 0,
        'message': '获取成功',
        'data': {
            'total': total,
            'pages': pages,
            'page': page,
            'per_page': per_page,
            'items': [code_to_dict(code) for code in codes]
        }
    }

    return jsonify(result)


@admin_blueprint.route('/activation_codes/<int:code_id>', methods=['GET'])
@jwt_required()
def get_activation_code_underscore(code_id):
    """获取激活码详情（带下划线的路由）"""
    return get_activation_code(code_id)


@admin_blueprint.route('/activation-codes/<int:code_id>', methods=['GET'])
@jwt_required()
def get_activation_code(code_id):
    """获取激活码详情"""
    code = ActivationCode.query.get_or_404(code_id)

    return jsonify({
        'code': 0,
        'message': '获取成功',
        'data': code_to_dict(code)
    })


@admin_blueprint.route('/activation_codes/generate', methods=['POST'])
@jwt_required()
@admin_required
def generate_activation_codes_underscore():
    """生成一批激活码（带下划线的路由）"""
    return generate_activation_codes()


@admin_blueprint.route('/activation-codes/generate', methods=['POST'])
@jwt_required()
def generate_activation_codes():
    """生成一批激活码"""
    # 检查JWT权限
    claims = get_jwt()
    if claims.get('is_test'):
        return jsonify({'code': 1, 'message': '测试账号不能生成激活码'}), 403

    data = request.json

    count = data.get('count', 10)  # 生成数量
    usage_count = data.get('usage_count', 10)  # 每个激活码可使用次数
    expire_days = data.get('expire_days', 30)  # 有效期天数，原名expire_days，也接受days参数
    if 'days' in data:  # 兼容days参数
        expire_days = data.get('days')
    remark = data.get('remark', '')  # 备注

    # 查询数据库中存在的代理
    first_agent = Agent.query.first()
    if not first_agent:
        # 如果没有代理，先创建一个默认用户，再创建代理
        from app.models import User
        # 检查是否有管理员用户
        admin_user = User.query.first()

        if not admin_user:
            # 如果没有用户，创建一个系统用户
            admin_user = User(
                nick_name="系统管理员",
                mobile="13800138000",
                create_time=datetime.datetime.now()
            )
            db.session.add(admin_user)
            db.session.flush()  # 获取用户ID
            print(f"已创建默认用户，ID={admin_user.user_id}")

        # 创建代理，使用已有用户ID
        first_agent = Agent(
            name="默认代理",
            user_id=admin_user.user_id,  # 使用已有用户ID
            status=1
        )
        db.session.add(first_agent)
        db.session.flush()  # 立即获取ID
        print(f"已创建默认代理，ID={first_agent.id}")
    else:
        print(f"使用现有代理，ID={first_agent.id}")

    # 使用存在的代理ID
    agent_id = first_agent.id

    # 验证参数
    if count <= 0 or count > 1000:
        return jsonify({'code': 1, 'message': '生成数量必须在1-1000之间'}), 400

    if usage_count <= 0:
        return jsonify({'code': 1, 'message': '使用次数必须大于0'}), 400

    # 创建批次
    batch_id = f"{datetime.datetime.now().strftime('%Y%m%d%H%M%S')}{random.randint(1000, 9999)}"

    batch = ActivationCodeBatch(
        id=batch_id,
        agent_id=agent_id,  # 使用查询到的代理ID
        count=count,
        usage_count=usage_count,
        expire_days=expire_days,
        remark=remark
    )

    db.session.add(batch)

    # 计算过期时间
    expire_time = None
    if expire_days:
        expire_time = datetime.datetime.now() + datetime.timedelta(days=expire_days)

    # 生成激活码
    codes = []

    for _ in range(count):
        # 使用通用函数生成唯一激活码
        code_str = generate_unique_code(prefix='045', length=8)

        code = ActivationCode(
            code=code_str,
            usage_count=usage_count,
            status=0,  # 未使用
            create_time=datetime.datetime.now(),
            expire_time=expire_time,
            remark=remark,
            created_by=agent_id,  # 使用查询到的代理ID
            batch_id=batch_id
        )

        codes.append(code)

    db.session.add_all(codes)

    # 添加操作日志
    admin_id = get_admin_id()
    log = AdminLog(
        admin_id=admin_id,
        action='生成激活码',
        ip=request.remote_addr,
        details=f'生成了{count}个激活码，每个可使用{usage_count}次'
    )

    db.session.add(log)
    db.session.commit()

    return jsonify({
        'code': 0,
        'message': '激活码生成成功',
        'data': {
            'batch_id': batch_id,
            'count': count,
            'codes': [code_to_dict(code) for code in codes[:10]]  # 只返回前10个
        }
    })


@admin_blueprint.route('/activation_codes/batch/<batch_id>', methods=['GET'])
@jwt_required()
def get_batch_codes_underscore(batch_id):
    """获取批次下的激活码（带下划线的路由）"""
    return get_batch_codes(batch_id)


@admin_blueprint.route('/activation-codes/batch/<batch_id>', methods=['GET'])
@jwt_required()
def get_batch_codes(batch_id):
    """获取批次下的激活码"""
    # 获取分页参数
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 20, type=int)

    # 获取批次信息
    batch = ActivationCodeBatch.query.get_or_404(batch_id)

    # 获取该批次下的激活码
    # 使用limit和offset代替paginate
    offset = (page - 1) * per_page
    query = ActivationCode.query.filter_by(batch_id=batch_id)
    total = query.count()
    codes = query.offset(offset).limit(per_page).all()

    # 计算总页数
    pages = (total + per_page - 1) // per_page if total > 0 else 1

    return jsonify({
        'code': 0,
        'message': '获取成功',
        'data': {
            'batch': {
                'id': batch.id,
                'agent_id': batch.agent_id,
                'count': batch.count,
                'usage_count': batch.usage_count,
                'expire_days': batch.expire_days,
                'create_time': batch.create_time.strftime('%Y-%m-%d %H:%M:%S'),
                'remark': batch.remark
            },
            'codes': {
                'total': total,
                'pages': pages,
                'page': page,
                'per_page': per_page,
                'items': [code_to_dict(code) for code in codes]
            }
        }
    })


@admin_blueprint.route('/activation_codes/batches', methods=['GET'])
@jwt_required()
def get_batches_underscore():
    """获取激活码批次列表（带下划线的路由）"""
    return get_batches()


@admin_blueprint.route('/activation-codes/batches', methods=['GET'])
@jwt_required()
def get_batches():
    """获取激活码批次列表"""
    # 获取分页参数
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 20, type=int)
    agent_id = request.args.get('agent_id', None, type=int)

    # 构建查询
    query = ActivationCodeBatch.query

    # 根据代理筛选
    if agent_id:
        query = query.filter(ActivationCodeBatch.agent_id == agent_id)

    # 执行分页查询
    # 使用limit和offset代替paginate
    offset = (page - 1) * per_page
    query = query.order_by(desc(ActivationCodeBatch.create_time))
    total = query.count()
    batches = query.offset(offset).limit(per_page).all()

    # 计算总页数
    pages = (total + per_page - 1) // per_page if total > 0 else 1

    # 构建响应数据
    result = {
        'code': 0,
        'message': '获取成功',
        'data': {
            'total': total,
            'pages': pages,
            'page': page,
            'per_page': per_page,
            'items': [{
                'id': batch.id,
                'agent_id': batch.agent_id,
                'agent_name': batch.agent.name if batch.agent else None,
                'count': batch.count,
                'usage_count': batch.usage_count,
                'expire_days': batch.expire_days,
                'create_time': batch.create_time.strftime('%Y-%m-%d %H:%M:%S'),
                'remark': batch.remark
            } for batch in batches]
        }
    }

    return jsonify(result)


@admin_blueprint.route('/activation-codes/delete/<int:code_id>', methods=['POST'])
@jwt_required()
@admin_required
def delete_activation_code(code_id):
    """删除激活码"""
    code = ActivationCode.query.get_or_404(code_id)

    # 如果激活码已被使用，不允许删除
    if code.status == 1:
        return jsonify({'code': 1, 'message': '已使用的激活码不能删除'}), 400

    # 添加操作日志
    admin_id = get_admin_id()
    log = AdminLog(
        admin_id=admin_id,
        action='删除激活码',
        ip=request.remote_addr,
        details=f'删除激活码 {code.code}'
    )

    db.session.add(log)

    # 删除激活码
    db.session.delete(code)
    db.session.commit()

    return jsonify({
        'code': 0,
        'message': '删除成功'
    })


@admin_blueprint.route('/activation-codes/mark-copied/<int:code_id>', methods=['POST'])
@jwt_required()
def mark_activation_code_copied(code_id):
    """标记激活码为已复制"""
    code = ActivationCode.query.get_or_404(code_id)

    code.is_copied = True
    code.copied_time = datetime.datetime.now()

    db.session.commit()

    return jsonify({
        'code': 0,
        'message': '标记成功',
        'data': code_to_dict(code)
    })


@admin_blueprint.route('/activation-codes/mark-exported/<int:code_id>', methods=['POST'])
@jwt_required()
def mark_activation_code_exported(code_id):
    """标记激活码为已导出"""
    code = ActivationCode.query.get_or_404(code_id)

    code.is_exported = True
    code.exported_time = datetime.datetime.now()

    db.session.commit()

    return jsonify({
        'code': 0,
        'message': '标记成功',
        'data': code_to_dict(code)
    })


@admin_blueprint.route('/activation-codes/batch-mark-copied', methods=['POST'])
@jwt_required()
def batch_mark_activation_codes_copied():
    """批量标记激活码为已复制"""
    data = request.json
    code_ids = data.get('code_ids', [])

    if not code_ids:
        return jsonify({
            'code': 1,
            'message': '请选择要标记的激活码'
        }), 400

    codes = ActivationCode.query.filter(ActivationCode.id.in_(code_ids)).all()
    current_time = datetime.datetime.now()

    for code in codes:
        code.is_copied = True
        code.copied_time = current_time

    db.session.commit()

    return jsonify({
        'code': 0,
        'message': f'成功标记{len(codes)}个激活码为已复制'
    })


@admin_blueprint.route('/activation-codes/batch-mark-exported', methods=['POST'])
@jwt_required()
def batch_mark_activation_codes_exported():
    """批量标记激活码为已导出"""
    data = request.json
    code_ids = data.get('code_ids', [])

    if not code_ids:
        return jsonify({
            'code': 1,
            'message': '请选择要标记的激活码'
        }), 400

    codes = ActivationCode.query.filter(ActivationCode.id.in_(code_ids)).all()
    current_time = datetime.datetime.now()

    for code in codes:
        code.is_exported = True
        code.exported_time = current_time

    db.session.commit()

    return jsonify({
        'code': 0,
        'message': f'成功标记{len(codes)}个激活码为已导出'
    })


@admin_blueprint.route('/activation-codes/statistics', methods=['GET'])
@jwt_required()
def get_activation_codes_statistics():
    """获取激活码各状态数量统计"""
    agent_id = request.args.get('agent_id', None, type=int)

    # 构建基础查询
    query = ActivationCode.query

    # 如果指定了代理ID，只查询该代理的激活码
    if agent_id:
        query = query.filter(ActivationCode.created_by == agent_id)

    # 获取各状态数量
    total_count = query.count()
    unused_count = query.filter(ActivationCode.status == 0).count()
    used_count = query.filter(ActivationCode.status == 1).count()
    copied_count = query.filter(ActivationCode.is_copied == True).count()
    exported_count = query.filter(ActivationCode.is_exported == True).count()

    # 最近生成的激活码
    recent_codes = query.order_by(desc(ActivationCode.create_time)).limit(5).all()

    return jsonify({
        'code': 0,
        'message': '获取成功',
        'data': {
            'total_count': total_count,
            'unused_count': unused_count,
            'used_count': used_count,
            'copied_count': copied_count,
            'exported_count': exported_count,
            'recent_codes': [code_to_dict(code) for code in recent_codes]
        }
    })


def code_to_dict(code):
    """将激活码对象转换为字典"""
    result = {
        'id': code.id,
        'code': code.code,
        'usage_count': code.usage_count,
        'status': code.status,
        'status_text': '已使用' if code.status == 1 else '未使用',
        'used_by': code.used_by,
        'used_time': code.used_time.strftime('%Y-%m-%d %H:%M:%S') if code.used_time else None,
        'create_time': code.create_time.strftime('%Y-%m-%d %H:%M:%S') if code.create_time else None,
        'expire_time': code.expire_time.strftime('%Y-%m-%d %H:%M:%S') if code.expire_time else None,
        'remark': code.remark,
        'created_by': code.created_by,
        'batch_id': code.batch_id,
        'is_copied': code.is_copied,
        'is_exported': code.is_exported,
        'copied_time': code.copied_time.strftime('%Y-%m-%d %H:%M:%S') if code.copied_time else None,
        'exported_time': code.exported_time.strftime('%Y-%m-%d %H:%M:%S') if code.exported_time else None
    }

    # 安全地获取代理名称
    try:
        # 使用模型查询而不是原生SQL查询
        if code.created_by:
            agent = Agent.query.filter(Agent.id == code.created_by).first()
            result['agent_name'] = agent.name if agent else None
        else:
            result['agent_name'] = None
    except Exception as e:
        current_app.logger.error(f"获取代理信息失败: {str(e)}")
        result['agent_name'] = None

    # 如果有用户，添加用户信息
    if code.user:
        try:
            result['user_info'] = {
                'user_id': code.user.user_id,
                'nick_name': code.user.nick_name,
                'mobile': code.user.mobile
            }
        except Exception as e:
            current_app.logger.error(f"获取用户信息失败: {str(e)}")
            result['user_info'] = {'user_id': code.used_by, 'nick_name': '未知用户', 'mobile': ''}

    return result


# 小程序专用无JWT验证接口
@admin_blueprint.route('/mp/check-permission', methods=['GET', 'OPTIONS'])
def mp_check_permission():
    """小程序专用：检查用户是否有代理权限（无JWT验证）"""
    user_id = request.args.get('user_id')

    if not user_id:
        return jsonify({"code": -1, "message": "用户ID不能为空"}), 400

    try:
        # 查询用户是否是代理
        agent = Agent.query.filter_by(user_id=user_id, status=1).first()

        if agent:
            # 有代理权限
            return jsonify({
                "code": 0,
                "message": "验证成功",
                "data": {
                    "has_permission": True,
                    "agent_info": {
                        "id": agent.id,
                        "name": agent.name,
                        "max_generation_count": agent.max_generation_count,
                        "used_generation_count": agent.used_generation_count,
                        "create_time": agent.create_time.strftime('%Y-%m-%d %H:%M:%S') if agent.create_time else None,
                        "level": agent.get_level_name(),
                        "avatar": agent.user.avatar_url if agent.user else None,
                        "commission_rate": agent.commission_rate,
                        "balance": float(agent.balance) if agent.balance else 0.0,
                        "status": agent.status,
                        "region": agent.region
                    }
                }
            })
        else:
            # 无代理权限
            return jsonify({
                "code": 0,
                "message": "验证成功",
                "data": {
                    "has_permission": False
                }
            })
    except Exception as e:
        current_app.logger.error(f"验证权限失败: {str(e)}")
        return jsonify({"code": -1, "message": f"验证权限失败: {str(e)}"}), 500


@admin_blueprint.route('/mp/activation-codes', methods=['GET'])
def mp_get_activation_codes():
    """小程序专用：获取激活码列表（无JWT验证）"""
    try:
        # 获取查询参数
        per_page = int(request.args.get('per_page', 20))
        status = request.args.get('status', type=int)
        is_copied = request.args.get('is_copied', type=int)
        is_exported = request.args.get('is_exported', type=int)
        agent_id = request.args.get('agent_id', type=int)
        expire_days = request.args.get('expire_days', type=int)
        usage_count = request.args.get('usage_count', type=int)
        # 构建查询
        query = ActivationCode.query

        if status is not None:
            query = query.filter_by(status=status)

        if usage_count is not None:
            query = query.filter_by(usage_count=usage_count)

        if is_copied is not None:
            query = query.filter_by(is_copied=bool(is_copied))

        if is_exported is not None:
            query = query.filter_by(is_exported=bool(is_exported))

        if agent_id is not None:
            query = query.filter_by(created_by=agent_id)

        if expire_days is not None:
            if expire_days == 0:
                query = query.filter(ActivationCode.expire_time.is_(None))
            else:
                query = query.filter(ActivationCode.expire_days == expire_days)

        # 直接获取最多per_page条数据
        items = query.limit(per_page).all()
        total = len(items)  # 简化计算，总数就是返回的数量

        return jsonify({
            "code": 0,
            "message": "获取成功",
            "data": {
                "items": [code_to_dict(code) for code in items],
                "page": 1,
                "per_page": per_page,
                "total": total
            }
        })
    except Exception as e:
        current_app.logger.error(f"获取激活码列表失败: {str(e)}")
        return jsonify({"code": -1, "message": f"获取激活码列表失败: {str(e)}"}), 500


@admin_blueprint.route('/mp/activation-codes/statistics', methods=['GET'])
def mp_get_activation_codes_statistics():
    """小程序专用：获取激活码统计信息（无JWT验证）"""
    try:
        agent_id = request.args.get('agent_id', type=int)

        # 构建基础查询
        query = ActivationCode.query

        # 如果指定了代理ID，只查询该代理的激活码
        if agent_id:
            query = query.filter(ActivationCode.created_by == agent_id)

        # 获取各状态数量
        total_count = query.count()
        unused_count = query.filter(ActivationCode.status == 0).count()
        used_count = query.filter(ActivationCode.status == 1).count()
        copied_count = query.filter(ActivationCode.is_copied == True).count()
        exported_count = query.filter(ActivationCode.is_exported == True).count()

        return jsonify({
            'code': 0,
            'message': '获取成功',
            'data': {
                'total_count': total_count,
                'unused_count': unused_count,
                'used_count': used_count,
                'copied_count': copied_count,
                'exported_count': exported_count
            }
        })
    except Exception as e:
        current_app.logger.error(f"获取统计信息失败: {str(e)}")
        return jsonify({"code": -1, "message": f"获取统计信息失败: {str(e)}"}), 500


@admin_blueprint.route('/mp/activation-codes/mark-copied/<int:code_id>', methods=['POST'])
def mp_mark_activation_code_copied(code_id):
    """小程序专用：标记激活码为已复制（无JWT验证）"""
    try:
        code = ActivationCode.query.get_or_404(code_id)

        code.is_copied = True
        code.copied_time = datetime.datetime.now()

        db.session.commit()

        return jsonify({
            'code': 0,
            'message': '标记成功',
            'data': {
                'copied_time': code.copied_time.strftime('%Y-%m-%d %H:%M:%S') if code.copied_time else None
            }
        })
    except Exception as e:
        current_app.logger.error(f"标记为已复制失败: {str(e)}")
        return jsonify({"code": -1, "message": f"操作失败: {str(e)}"}), 500


@admin_blueprint.route('/mp/activation-codes/mark-exported/<int:code_id>', methods=['POST'])
def mp_mark_activation_code_exported(code_id):
    """小程序专用：标记激活码为已导出（无JWT验证）"""
    try:
        code = ActivationCode.query.get_or_404(code_id)

        code.is_exported = True
        code.exported_time = datetime.datetime.now()

        db.session.commit()

        return jsonify({
            'code': 0,
            'message': '标记成功',
            'data': {
                'exported_time': code.exported_time.strftime('%Y-%m-%d %H:%M:%S') if code.exported_time else None
            }
        })
    except Exception as e:
        current_app.logger.error(f"标记为已导出失败: {str(e)}")
        return jsonify({"code": -1, "message": f"操作失败: {str(e)}"}), 500


@admin_blueprint.route('/mp/activation-codes/batch-mark-copied', methods=['POST'])
def mp_batch_mark_activation_codes_copied():
    """小程序专用：批量标记激活码为已复制（无JWT验证）"""
    try:
        data = request.json
        code_ids = data.get('code_ids', [])

        if not code_ids:
            return jsonify({
                'code': 1,
                'message': '请选择要标记的激活码'
            }), 400

        codes = ActivationCode.query.filter(ActivationCode.id.in_(code_ids)).all()
        current_time = datetime.datetime.now()

        for code in codes:
            code.is_copied = True
            code.copied_time = current_time

        db.session.commit()

        return jsonify({
            'code': 0,
            'message': f'成功标记{len(codes)}个激活码为已复制',
            'data': {
                'affected_count': len(codes)
            }
        })
    except Exception as e:
        current_app.logger.error(f"批量标记为已复制失败: {str(e)}")
        return jsonify({"code": -1, "message": f"操作失败: {str(e)}"}), 500


@admin_blueprint.route('/mp/activation-codes/batch-mark-exported', methods=['POST'])
def mp_batch_mark_activation_codes_exported():
    """小程序专用：批量标记激活码为已导出（无JWT验证）"""
    try:
        data = request.json
        code_ids = data.get('code_ids', [])

        if not code_ids:
            return jsonify({
                'code': 1,
                'message': '请选择要标记的激活码'
            }), 400

        codes = ActivationCode.query.filter(ActivationCode.id.in_(code_ids)).all()
        current_time = datetime.datetime.now()

        for code in codes:
            code.is_exported = True
            code.exported_time = current_time

        db.session.commit()

        return jsonify({
            'code': 0,
            'message': f'成功标记{len(codes)}个激活码为已导出',
            'data': {
                'affected_count': len(codes)
            }
        })
    except Exception as e:
        current_app.logger.error(f"批量标记为已导出失败: {str(e)}")
        return jsonify({"code": -1, "message": f"操作失败: {str(e)}"}), 500


@admin_blueprint.route('/mp/activation-codes/generate', methods=['POST'])
def mp_generate_activation_codes():
    """小程序专用：生成激活码（无JWT验证）"""
    try:
        data = request.json

        count = data.get('count', 1)
        agent_id = data.get('agent_id')
        usage_count = data.get('usage_count', 1)  # 获取使用次数参数
        expire_days = data.get('expire_days', 0)

        if count <= 0 or count > 1000:
            return jsonify({"code": -1, "message": "生成数量应在1-1000之间"}), 400

        if not agent_id:
            return jsonify({"code": -1, "message": "代理ID不能为空"}), 400

        # 查询代理信息，确认代理存在
        agent = Agent.query.get(agent_id)
        if not agent:
            return jsonify({"code": -1, "message": "代理不存在"}), 404

        # 计算需要扣除的总次数
        total_usage = count * usage_count

        # 检查代理剩余可生成次数是否足够
        remaining_count = agent.max_generation_count - agent.used_generation_count
        if remaining_count < total_usage:
            return jsonify(
                {"code": -1, "message": f"剩余可生成次数不足，当前剩余: {remaining_count}，需要: {total_usage}"}), 400

        # 创建激活码批次
        batch_id = str(uuid.uuid4()).replace('-', '')[:16]
        current_time = datetime.datetime.now()

        # 创建批次记录
        batch = ActivationCodeBatch(
            id=batch_id,
            agent_id=agent_id,
            count=count,
            usage_count=usage_count,
            expire_days=expire_days
        )
        db.session.add(batch)

        # 计算过期时间
        expire_time = None
        if expire_days > 0:
            expire_time = current_time + datetime.timedelta(days=expire_days)

        # 生成激活码
        codes = []

        for _ in range(count):
            # 使用通用函数生成唯一激活码
            code_str = generate_unique_code(prefix='045', length=11)

            # 创建激活码对象
            code = ActivationCode(
                code=code_str,
                usage_count=usage_count,  # 设置使用次数
                status=0,
                is_copied=False,
                is_exported=False,
                created_by=agent_id,
                create_time=current_time,
                expire_time=expire_time,
                batch_id=batch_id
            )

            db.session.add(code)
            codes.append(code)

        # 更新代理已使用的生成次数
        agent.used_generation_count = agent.used_generation_count + total_usage

        db.session.commit()

        return jsonify({
            'code': 0,
            'message': f'成功生成{count}个激活码',
            'data': {
                'count': count,
                'codes': [code_to_dict(code) for code in codes[:10]],  # 只返回前10个
                'agent': {
                    'remaining_count': agent.max_generation_count - agent.used_generation_count,
                    'used_count': agent.used_generation_count,
                    'max_count': agent.max_generation_count
                }
            }
        })
    except Exception as e:
        db.session.rollback()
        print(f"生成激活码失败: {str(e)}")
        return jsonify({"code": -1, "message": f"生成失败: {str(e)}"}), 500


@admin_blueprint.route('/activation-codes/stats', methods=['GET', 'OPTIONS'])
@jwt_required(optional=True)
def get_activation_codes_stats():
    """获取激活码统计信息
    
    查询参数:
    - status: 状态筛选（0-未使用，1-已使用）
    - usage_count: 按使用次数筛选
    
    返回:
    - 符合条件的激活码数量和各使用次数的统计
    """
    status = request.args.get('status', None)
    usage_count = request.args.get('usage_count', None)

    # 构建查询
    query = ActivationCode.query

    # 根据状态筛选
    if status is not None:
        try:
            status_int = int(status)
            query = query.filter(ActivationCode.status == status_int)
        except (ValueError, TypeError):
            pass

    # 根据使用次数筛选
    if usage_count is not None:
        try:
            usage_count_int = int(usage_count)
            query = query.filter(ActivationCode.usage_count == usage_count_int)
        except (ValueError, TypeError):
            pass

    # 计算符合条件的总数
    total_count = query.count()

    # 统计不同使用次数的数量
    usage_count_stats = {}
    if status is not None:  # 只有在指定状态时才统计使用次数分布
        for count in range(0, 101):  # 假设使用次数范围为0-100
            count_query = query.filter(ActivationCode.usage_count == count)
            count_num = count_query.count()
            if count_num > 0:  # 只记录有数据的使用次数
                usage_count_stats[str(count)] = count_num

    # 构建响应数据
    result = {
        'code': 0,
        'message': '获取成功',
        'data': {
            'total': total_count,
            'usage_count_stats': usage_count_stats
        }
    }

    # 返回响应
    return jsonify(result)


@admin_blueprint.route('/activation-codes/export', methods=['GET', 'OPTIONS'])
@jwt_required(optional=True)
def get_activation_codes_to_export():
    """获取要导出的激活码列表
    
    查询参数:
    - status: 状态筛选（0-未使用，1-已使用）
    - usage_count: 按使用次数筛选
    - limit: 限制返回数量，默认100
    - is_copied : 是否已经复制
    - agency : 代理ID筛选
    返回:
    - 符合条件的激活码列表
    """
    # 获取参数
    status = request.args.get('status', None)
    usage_count = request.args.get('usage_count', None)
    limit = request.args.get('limit', 100, type=int)
    created_by = request.args.get('created_by', None, type=int)
    is_copied = request.args.get('is_copied', None, type=int)
    # 限制最大导出数量，防止系统负载过高
    if limit > 1000:
        limit = 1000
    if not created_by:
        return jsonify({
            'code': 1,
            'message': '请提供代理ID'
        }), 400
    # 构建查询
    query = ActivationCode.query

    # 根据状态筛选
    if status is not None:
        try:
            status_int = int(status)
            query = query.filter(ActivationCode.status == status_int)
        except (ValueError, TypeError):
            pass
    if created_by is not None:
        try:
            created_by_int = int(created_by)
            query = query.filter(ActivationCode.created_by == created_by_int)
        except (ValueError, TypeError):
            pass
    if is_copied is not None:
        try:
            is_copied_bool = bool(int(is_copied))
            query = query.filter(ActivationCode.is_copied == is_copied_bool)
        except (ValueError, TypeError):
            pass
    # 根据使用次数筛选
    if usage_count is not None:
        try:
            usage_count_int = int(usage_count)
            query = query.filter(ActivationCode.usage_count == usage_count_int)
        except (ValueError, TypeError):
            pass

    # 执行查询，按创建时间倒序排序，优先导出最新的激活码
    codes = query.order_by(desc(ActivationCode.create_time)).limit(limit).all()
    # 更新导出的激活码状态为已导出（is_copied = True）
    for code in codes:
        code.is_copied = True  # 设置为已导出

    # 提交数据库变更
    db.session.commit()
    # 构建响应数据
    result = {
        'code': 0,
        'message': '获取成功1',
        'data': {
            'total': len(codes),
            'items': [code_to_dict(code) for code in codes]
        }
    }

    # 返回响应
    return jsonify(result)
